/**
   \file  exceptions.hh
   \brief Some common exception classes.

   This file defines an exceptions base class meant to be used by all the
   libgist driver modules. It also defines some exception classes for
   denoting exceptional conditions common to all the drivers.
*/

/*
   This file is part of libgist.

   libgist is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2 of the License, or (at your
   option) any later version.

   libgist is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
   for more details.

   You should have received a copy of the GNU General Public License
   along with libgist; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/

/*
   REVISION HISTORY

   $HeadURL: http://libgist.googlecode.com/svn/trunk/drv/exceptions.hh $
   $Id: exceptions.hh 41 2011-08-22 08:51:48Z libgist@gmail.com $
*/

#ifndef GISTDRV_EXCEPTIONS_DOT_HH
#define GISTDRV_EXCEPTIONS_DOT_HH

//------------------------------ HEADERS --------------------------------

// Standard C++ headers
#include <stdexcept>
#include <string>

//----------------------- NAMESPACE DEFINITION --------------------------

namespace gistdrv {

//------------------------- CLASS DEFINITION ----------------------------

/**
   \brief A common exception class.

   This is a base class for the different exceptional coditions
   encountered by the various libgist driver program's modules. In
   addition to the error message support provided by std::runtime_error,
   this class provides for an error code that can be used as the
   program's return value to the OS environment/shell.
*/
/*
   A NOTE ON ERROR CODE POLICY:

   Each libgist driver program module gets a range of error codes. Error
   codes 1 through 10 are reserved for use by the main program as is
   error code 255. The first module to be implemented gets the range 11
   through 20; the next one 21 through 30; the third one 31 through 40;
   so on and so forth.

   There is no central arbiter to automatically assign new these ranges
   to different modules. When implementing a new module, developers
   should look at the existing codebase and pick a range that is not
   already in use.
*/
class exception: public std::runtime_error {
protected:
   /// In addition to an error message (support provided by base class),
   /// this exception class also records an error code.
   /// \return
   int m_code ;

   /**
      \brief Initialize exception using appropriate error code and message.
      \param code Error code associated with exception.
      \param msg Error message associated with exception.

      This class is not meant to be instantiated directly. Clients should
      subclass this class and use those subclasses instead. Hence the
      protected constructor. On instantiation, subclasses should provide
      both an error code as well as an error message.
   */
   exception(int code, const std::string& msg) ;

public:
   /// Accessor to return the exception's error code.
   int code() const throw() {return m_code ;}
} ;

//---------------------- SOME COMMON EXCEPTIONS -------------------------

/**
   \brief Exception indicating unsupported driver action.

   The libgist driver program contains several different algorithm
   drivers, one per algorithm provided by libgist. Each driver supports a
   set of algorithm-sepcific actions. The user must specify both the
   algorithm to test-drive as well as its action via command line
   arguments to the gist program. If the user supplies an action that is
   unknown or unsupported by the requested algorithm, an error will be
   reported via an instance of this class.
*/
struct unknown_action: public exception {
   /**
      \brief Specify error code and message for unsupported action.
      \param error_code Code identifying unsupported action.
      \param algo_name Name of the algorithm that doesn't support the action.
      \param action Name of the unsupported action.

      To report a useful error message when an unsupported algorithm
      action is requested, clients should supply a suitable error code
      along with the name of the algorithm and the action when creating
      this exception object.
   */
   unknown_action(int error_code,
                  const std::string& algo_name, const std::string& action) ;
} ;

/**
   \brief Exception indicating failure to open file for writing.

   Any libgist driver program module can throw an instance of this class
   when it tries to open a file for writing and fails for some reason
   (e.g., permission problems, disk full).
*/
struct unable_to_create_file: public exception {
   /**
      \brief Specify error code and file name for file creation error.
      \param error_code Code identifying file creation error.
      \param file_name Name of file that could not be created.

      To report a useful error message when a client module fails to open
      a file for writing, it should supply a suitable error code as well
      as the name of the file that could not be opened.
   */
   unable_to_create_file(int error_code, const std::string& file_name) ;
} ;

//-----------------------------------------------------------------------

} // end of namespace encapsulating this file's definitions

#endif

/* So things look consistent in everyone's emacs... */
/* Local Variables: */
/* indent-tabs-mode: nil */
/* End: */
